Skip to content

Release 1.3.20 — domains CLI, Remotion fix, new commands - #11

Merged
mayoalexander merged 4 commits into
mainfrom
dev
May 2, 2026
Merged

Release 1.3.20 — domains CLI, Remotion fix, new commands#11
mayoalexander merged 4 commits into
mainfrom
dev

Conversation

@mayoalexander

Copy link
Copy Markdown

Summary

  • iris hive domains proxy/list/remove — manage domain mappings + Cloudflare from CLI
  • Remotion output path fix (renders to CWD instead of ~/.iris/remotion/)
  • New commands: platform-device, platform-clips, and more

Test plan

  • iris hive domains list shows existing mappings
  • iris hive domains proxy comic https://comic-book-factory.vercel.app --base-domain freelabel.net creates mapping
  • iris remotion render SocialPost outputs to ./out/SocialPost.mp4

🤖 Generated with Claude Code

mayoalexander and others added 4 commits May 1, 2026 16:20
render and still commands didn't pass an output path, so Remotion
defaulted to its project dir (~/.iris/remotion/out/). Now defaults
to $PWD/out/<composition>.<ext> and prints the path.

Fixes #77344, #77345

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…stry)

Atlas Datasets CLI (iris atlas:datasets):
- schemas list/show/create — manage dataset blueprints
- records list/show/summary/add/update/delete/upsert — full CRUD
- export — CSV/JSON export for QuickBooks Desktop
- audit — data quality scan (flags $0 billing, missing fields)

Genesis Validation:
- validateComponents() now async — fetches valid types from API
- Fallback to 152-type hardcoded set when API unreachable
- pages set now validates before API call
- VALID_COMPONENT_TYPES expanded from 30 → 152 (all Vue components)
- COMPONENT_REGISTRY expanded with categories + required props
- component-registry command fetches from API with category grouping

How-To Recipes (3 new):
- atlas-datasets.md — general dataset CLI usage
- pathways-cfo-workflow.md — Servis AI → Atlas → QuickBooks pipeline
- expose-dataset-api.md — REST API + pages + agent access

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ands

- Fix deals create: billing_interval → interval (wrong payload key)
- Fix deals create: choices one_time/monthly → one-time/month (API mismatch)
- Add deals delete: cancel existing payment gate via CLI
- Add deals update: modify amount/scope/interval/fees on existing gate
- Add --pass-fees/--absorb-fees/--fee-percent/--fee-flat to create & update
- Update command preserves interval from existing deal billing_type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds `iris hive domains proxy <subdomain> <target>` which:
1. Creates Cloudflare DNS record (via wrangler)
2. Creates Cloudflare Worker route (via wrangler)
3. Creates domain mapping in fl-api

Also adds `iris hive domains list` and `iris hive domains remove`.

Example: iris hive domains proxy comic https://comic-book-factory.vercel.app
  → comic.heyiris.io proxied to the Vercel app

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 2, 2026 03:09
@mayoalexander
mayoalexander merged commit 415c71b into main May 2, 2026
0 of 4 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This release expands the IRIS CLI with new Atlas dataset write capabilities, Hive domain mapping/proxy management, and improved Pages component validation/registry handling, alongside documentation scaffolds for Atlas datasets and a Remotion output-path adjustment.

Changes:

  • Add new “how-to” scaffold docs for Atlas datasets usage, exposing dataset APIs, and the Pathways CFO workflow.
  • Update CLI behavior for Remotion default output paths and Pages component validation/registry fetching.
  • Add/extend CLI commands for Atlas datasets (schema create + record CRUD/upsert), Hive domains proxy/list/remove, and Deals payment-gate update/delete.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
scaffold/how-to/pathways-cfo-workflow.md New end-to-end workflow recipe for Pathways CFO pipeline.
scaffold/how-to/expose-dataset-api.md New recipe describing REST access patterns for Atlas datasets.
scaffold/how-to/atlas-datasets.md New general recipe for Atlas datasets CLI usage.
scaffold/how-to/README.md Adds recipe index entries for new how-to docs.
packages/opencode/src/cli/cmd/platform-remotion.ts Changes default render/still outputs to ./out/... and prints output path.
packages/opencode/src/cli/cmd/platform-pages.ts Switches public URL base, makes component validation async with API-backed registry, and expands component registry output.
packages/opencode/src/cli/cmd/platform-leads.ts Adjusts deals payment-gate interval + adds update/delete commands + processing fee flags.
packages/opencode/src/cli/cmd/platform-hive.ts Adds iris hive domains proxy/list/remove with Cloudflare + fl-api domain mapping integration.
packages/opencode/src/cli/cmd/platform-atlas-datasets.ts Adds schema create and record write commands (add/update/delete/upsert).
packages/opencode/src/cli/cmd/command-groups.ts Categorizes atlas:datasets under the atlas command group.
Comments suppressed due to low confidence (1)

packages/opencode/src/cli/cmd/platform-hive.ts:11

  • This file redefines IRIS_API locally instead of using the exported IRIS_API/PLATFORM_URLS from cli/cmd/iris-api.ts, which is the repo’s single source of truth for platform base URLs. Using the shared constant avoids drift (e.g., different defaults/fallbacks) and respects the ~/.iris/sdk/.env preload logic in iris-api.ts.
// Use iris-api base for Hive endpoints
const IRIS_API = process.env.IRIS_API_URL ?? "https://freelabel.net"

async function hiveFetch(path: string, options: RequestInit = {}) {
  return irisFetch(path, options, IRIS_API)
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2787 to +2791
await flApiFetch(`/api/v1/domain-mappings/${existing.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ proxy_target: target, mapping_mode: "proxy", mapping_type: "proxy" }),
})
Comment on lines +2721 to +2726
// Create DNS A record (proxied, dummy IP — Worker intercepts)
try {
execSync(
`npx wrangler dns create ${baseDomain} --type A --name ${sub} --content 192.0.2.1 --proxied`,
{ stdio: "pipe", timeout: 30000 }
)
Comment on lines +3323 to +3324
if (!args.amount && !args.scope && !args.interval && !args["pass-fees"] && !args["absorb-fees"]) {
prompts.log.error("Provide at least one field to update: --amount, --scope, --interval, or --pass-fees")
Comment on lines +3340 to +3342
// Delete existing and recreate with updated values
const delRes = await irisFetch(`/api/v1/leads/${args.id}/payment-gate`, { method: "DELETE" })
if (!(await handleApiError(delRes, "Remove existing payment gate"))) return
Comment on lines +83 to +90
## Data flow diagram
```
Service AI ──→ IRIS Agent ──→ Atlas Dataset (cases) ──→ CSV Export
↓ ↓ ↓ ↓
Case details Aggregates Audit flags QuickBooks
+ Services from Drive $0 billing Desktop
+ Billing + Email Missing docs import
```
Comment on lines +247 to +259
// Validate components if the update touches json_content.components
if (args.path.startsWith("json_content.components") || args.path === "json_content") {
const target = args.path === "json_content" ? parsed : json
const validation = await validateComponents(target)
if (!validation.valid) {
sp.stop("Validation failed", 1)
for (const err of validation.errors) {
if (err) prompts.log.error(err)
}
prompts.outro("Done")
return
}
}
Comment on lines +740 to +760
async function getValidComponentTypes(): Promise<Set<string>> {
if (_cachedValidTypes) return _cachedValidTypes

try {
const { IRIS_API } = await import("./iris-api")
const res = await irisFetch("/api/v1/pages/schema-registry", {}, IRIS_API)
if (res.ok) {
const body = (await res.json()) as any
const types: string[] = body?.data?.types ?? []
if (types.length > 0) {
_cachedValidTypes = new Set(types)
return _cachedValidTypes
}
}
} catch {
// API unreachable — use fallback
}

_cachedValidTypes = FALLBACK_COMPONENT_TYPES
return _cachedValidTypes
}
Comment on lines 21 to 25
const env = process.env.IRIS_ENV ?? "production"
return env === "local"
? `http://local.iris.freelabel.net:9300/p/${slug}`
: `https://heyiris.io/p/${slug}`
: `https://freelabel.net/p/${slug}`
}
Comment on lines +54 to +56
const comp = args.composition as string
const output = (args.output as string) || join(process.cwd(), "out", `${comp}.mp4`)
const cmdArgs = ["render", comp, output]
Comment on lines +2685 to +2689
const FL_API = process.env.FL_API_URL ?? "https://raichu.heyiris.io"

async function flApiFetch(path: string, options: RequestInit = {}) {
return irisFetch(path, options, FL_API)
}
mayoalexander added a commit that referenced this pull request Aug 6, 2026
…ing's dead route

TWO THINGS, ONE WORKFLOW.

1. FIX — leads:meeting POSTed /api/chat/start, which is DEAD. It 404s on every call.
   platform-eval.ts already hit and fixed this exact failure (#146509: "the old harness
   POSTed to the dead raichu.heyiris.io/api/chat/start route → 404 on every test →
   false 0/7") by switching to streamAgentChat. leads:meeting never got the same fix, so
   a command whose entire purpose is turning a transcript into lead intel has been failing
   at the last step — AFTER reading the file and printing "Analyzing transcript with AI…",
   which makes it look supported right up until it produces nothing.
   Its default agent was also hardcoded to #11, which returns "Resource not found".

2. NEW — `iris meetings`. Wispr Flow keeps one directory per meeting under
   ~/Library/Application Support/Wispr Flow/meetings/<uuid>/refined.ndjson. Nothing
   surfaced it, so using a call meant finding the UUID by hand, converting NDJSON, and
   passing a path. Now:

     iris meetings                                  list recent sessions
     iris meetings 8ba439fd --bloq 570              summarise + file it
     iris meetings 8ba439fd --export out.txt        just the transcript
     iris meetings 8ba439fd --bloq 570 --raw        verbatim, no AI

   Sessions resolve by id prefix. --bloq finds or CREATES a "Meetings" list, so every
   client project accumulates its calls in the same place without anyone deciding where
   they go — a standard workflow rather than a convention people have to remember.

DELIBERATE CHOICES:
- Speakers are surfaced as diarised ids, not guessed names. Diarisation splits one person
  across ids routinely; a wrong name silently mis-attributes a commitment, which is worse
  than no name. --speaker 2=Arthur labels them when you know.
- Every export carries a header saying Wispr records SYSTEM audio, so your own mic may be
  absent and one side of the conversation can be missing. Verified on a real 56-minute
  client call where the local speaker was entirely uncaptured — reading that transcript
  without the warning would give a confidently one-sided account.
- Extraction failure is NOT fatal. It falls back to filing the raw transcript, because a
  filed transcript beats a lost meeting.
- The extraction prompt forbids inventing names, numbers, dates or commitments, and asks
  it to flag one-sidedness rather than infer the missing half.

Verified end to end on a real 222-segment, 56:47 client call: listed, extracted, created
the Meetings list on bloq 570 and filed item #179213 with accurate decisions and owners.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017HeisVSNVkwQPv3zvoJJUA
mayoalexander added a commit that referenced this pull request Aug 19, 2026
…ed on a 404

`iris integrations list` collapsed every probe failure into "unverified — could
not probe", which tells the reader nothing and cost real debugging hours.

Two worse bugs surfaced while fixing that:

1. The gmail and google-drive probes returned "verified" for ANY response that
   was not 401/403 — including 404 and 500. Both probe endpoints currently 404
   (/api/v1/leads/0/gmail-threads, /api/v1/integrations/exec), so Gmail has been
   rendering a green [verified] while its probe does not resolve at all. The
   health signal on those rows was meaningless.

2. Probe results were keyed by integration TYPE, not id, and the drive probe
   never passed integration_id. All three google-drive accounts (#4, #11, #12)
   therefore shared one result taken from whichever connection the API picks by
   default — two accounts could be dead and every row would show the third's
   status. The comment directly above that code says multi-account visibility is
   the point of the command.

Changes:

- Probes return { state, reason, fix } instead of a bare string, so every row
  states its cause and, where one exists, the command that fixes it.
- New "unknown" state, distinct from failure. A 404 on the PROBE path means we
  cannot determine the integration's health; claiming either verified or
  unverified would be unsupported. Rendered neutral rather than red, because the
  fix belongs to us, not the user.
- Network failures are classified — connection refused / timeout / DNS — rather
  than collapsing into one string.
- Results keyed by integration id; the drive probe passes integration_id so each
  account is genuinely probed.
- The calendar probe distinguishes bridge-not-running, no-bridge-key,
  key-rejected and HTTP-n, each with `iris hive doctor` as the fix.

    before  gmail #3            [verified]
    after   gmail #3            [unknown] — probe endpoint returned 404; status not determined
    before  google-calendar #2  [unverified] — could not probe
    after   google-calendar #2  [unverified] — no bridge key configured → iris hive doctor

Verified by running the command from source, not by reading the diff. Typecheck
clean; the remaining tsc error (session/llm.ts:88 TS2589) is pre-existing and
reproduces with this change stashed.

Refs #180929, #181016

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mayoalexander added a commit that referenced this pull request Sep 5, 2026
`iris eval run` reported "Tests passed 7/7". It counted every non-empty reply as
a pass:

    const passed = results.filter((r) => r.status === "completed").length
    // "completed" = summary.trim().length > 0

Four of the seven scenarios asserted NOTHING — introduction, creative,
tool-awareness, summary — so they passed by existing. The two that did have
keyword checks had their results printed and then excluded from the count. The
number could not go down, which made it a liveness probe wearing a score's
clothes.

Two changes.

1. A test with no assertion cannot pass; it can only run. Verdicts are now
   pass | fail | unscored, and the summary reads "3 / 3 scored · 4 unscored
   (ran, asserted nothing)" instead of 7/7. Same agent, same run, honest number.

2. A second suite that tests THIS agent rather than the model underneath it.
   `core` (Eiffel Tower, 17*24, a haiku) passes identically whether the agent's
   tools, YAML registry and integrations work or are entirely broken, because
   none of it is exercised. `agent` asserts:

     tool-use        the agent CALLED a tool — toolsUsed non-empty. The old
                     "what tools do you have?" is a self-report the agent will
                     happily give from its prompt header while every one of them
                     is unreachable.
     grounding       it reached the workspace at all
     no-fabrication  it declines to invent when asked about something that does
                     not exist

Verified against PATTY (anomalyco#420), not asserted: tool-use called
Pathways_get_firm_directory, grounding called SearchKnowledgeBaseTool. And it
fails honestly — agent #11 returned "Resource not found" and scored 0/3 rather
than passing vacuously.

no-fabrication is documented in-code as flaky BY CONSTRUCTION, because it is a
lexical proxy for a semantic property: the same agent on the same prompt hedged
in wording my list matched once and missed twice. The caveat says to read the
reply on a failure rather than conclude fabrication, and not to put it in a
threshold. Better to ship the limitation written down than a check that looks
deterministic and is not.

No MCP change. `iris_run` already executes any CLI command, so the MCP server
stays at seven tools and picks this up for free.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQ9915AheUUs2qL2D2u62K
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants